//@author A0083782W
//I think we will need some very common functions that are
//not dependent on any existing class, let's just put it here
//So everyone can benefit from it :-)
//Please create your own namespace for each of your own code
#pragma once

#include <ctime>
#include <string>
#include <vector>
#include "CommonDataType.h"

using std::vector;

//This namespace contains a function to get the curreny time.
//TimeType is the enum for type
//E.g. Get current year?
//currentYear = getCurrenTime (TimeType::YEAR);
//Please note that this function is not very fast, it saves space though
//If you need to use a faster function but a large memory usage,
//Search for "CurrentTime.h"
//Done by Chi Cheng
namespace GetCurrentTimeFunctions {

	enum class TimeType {
		YEAR = 1,
		MONTH = 2,
		DAY = 3,
		HOUR = 4,
		MINUTE = 5,
		SECOND = 6,
		DAYOFWEEK = 7
	};

	using CommonDataType::ByteInt;
	ByteInt getCurrentTime(TimeType);
};

//This namespace StringManipulator mainly contains functions that will help in
//the UserCommand class to analyse and translate a user command.
//I fear that you might need some of them as well. Anyway they are static functions,
//not related to any class, therefore I put it there
//Done by Chi Cheng
namespace StringManipulator {
	
	using CommonDataType::pos_int;
	using CommonDataType::con_str;
	using CommonDataType::con_chr;
	using std::string;
	using std::vector;

	const string NULL_STRING = "";
	
	//ignoreCase will put everything of the parameter string into lowercase.
	//void ignoreCase perform the operation on the original string
	//string ignoreCase return a new string without modifying the previous ones.
	void ignoreCase (string* mainString);
	string ignoreCase (con_str& mainString);

	//isCaptialLetter will return whether the character mainChar is
	//a captital letter or not
	bool isCapitalLetter (con_chr& mainChar);

	//splitString function will split the orignal string into words
	//These words will be stored inside the vector stringList
	//No. of words inside the list will be returned.
	//Words are separated by common punctuation specified by sepChar[] 
	int splitString (con_str& mainString, con_chr sepChar[], const pos_int sepCharSize,
					vector<string>& stringList, vector<pos_int>& indiceList);

	bool cutWordsFromString (con_str& mainString,con_chr sepChar[], const pos_int sepCharSize, vector<string>& stringList);
	//isEqualChar will check if mainChar is any of the members of
	//arrayChar[]. Return accordingly
	bool isEqualChar (con_chr& mainChar, con_chr arrayChar[], const pos_int sepCharSize);

	//If subString contains any of the characters in sepChar,
	//Or it is empty, it will return true
	//Else return false
	bool isIllegalString (con_str& subString, con_chr sepChar[], const pos_int sepCharSize);

	bool isLegalString (con_str& mainString, con_chr allowedChar[], const pos_int sepCharSize);
	//isSubString
	//Start from position, if the mainString has a part that is 
	//equal to subString, it will return true
	//Else, return false
	//E.g.
	//mainString == "Thisisgood", subString == "go", position == 6
	//return true
	bool isSubString (con_str& mainString, con_str& subString, 
						pos_int position);
	
	//CopySubString
	//Copy the part of mainString start from position until a sepChar is met
	//Return the copied string
	string copySubString (con_str& mainString, con_chr sepChar[], const pos_int sepCharSize, pos_int position);
	
	//isNumString
	//Check if the string consist of number only
	//Any symbol other than 0 to 9 will be recognised as illegal and return -1
	//E.g.
	//"0.001" is false. "-123" is false. "1232" is true.
	//When true, return the number value
	bool isNumString (con_str& mainString);
	
	//isEqualString will examine if mainString is equal to any member of the stringList
	//Return accordingly
	bool isEqualString (con_str& mainString, vector<con_str> const& stringList);
	bool isEqualString (con_str& mainString, con_str stringList[], const pos_int nSize);

	//find the number of occurance of the character specialChar inside the string mainString
	//return the number.
	pos_int findNumOfChar (con_str& mainString, con_chr specialChar);

	//Test is a string is empty.
	bool isNullString (con_str& mainString);

	//Delete all special Charater specChar inside the mainString
	int killChar (string& mainString, con_chr specChar);

	int filterChar (string& mainString, con_chr specChar[], pos_int specCharSize);

	//Detect if number is equal to any member of numberList
	bool isEqualInt (const int number, const int numberList[], const int nListMember);

	//look for all targetChar character in the mainstring and replace them with replaceChar.
	pos_int findAndReplace (string& mainString, con_chr targetChar, con_chr replaceChar);

	void capitaliseFirst (string& mainString);
	string capitaliseFirst (con_str& mainString);

	string getString (con_str& mainString, pos_int repeatNum);
	string getString (con_chr mainChar, pos_int repeatNum);

	string leftAlign (con_str& mainString, pos_int width);

	vector<string> splitLines (con_str& mainString, pos_int lineWidth, con_chr sepChar[], pos_int sepCharSize);

	string chopString (con_str& mainString, pos_int width);
};

#include "ConstantList.h"
namespace TimeManipulator {
	using CommonDataType::ByteInt;
	using GetCurrentTimeFunctions::TimeType;
	using CommonDataType::pos_int;
	using namespace TimeConstants;

	ByteInt getMaxDay(ByteInt year, Month month);
	bool isLeapYear (ByteInt yearValue);
	int getRandomNumber (int lowerLimit, int UpperLimit);
};

namespace VectorManipulator {
	template<typename T> bool isEqualVector(const vector<T>& operand1, const vector<T> & operand2) {
		if (operand1.size() != operand2.size()) {
			return false;
		}

		for (int i = 0; i < (int)operand1.size();i++) {
			if (operand1[i] != operand2[i]) {
				return false;
			}
		}

		return true;
	}
};